/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2010 Embedded Access Inc.;
* All Rights Reserved
**
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mpc83xx_etsec_prv.h$
* $Version : 3.8.1.0$
* $Date    : May-12-2011$
*
* Comments:
*
*   This file contains the Three Speed Ethernet Controller context for
*   mpc83xx platforms.
*
*END************************************************************************/

#ifndef __mpc83xx_etsec_prv_h__
#define __mpc83xx_etsec_prv_h__

#define MPC83XX_TSEC_DEFAULT_PHY_WAIT   (1000)

#define MPC83XX_TSEC_MAX_FRAGS     6     // Assumes RX_BUFFER_SIZE >= 256, so that 256*6=1536, set higher for smaller RX_BUFFER_SIZE

#define MPC83xx_ETH_MODE_MII   (0)
#define MPC83xx_ETH_MODE_GMII  (1)
#define MPC83xx_ETH_MODE_RGMII (2)
#define MPC83xx_ETH_MODE_TBI   (3)
#define MPC83xx_ETH_MODE_RTBI  (4)

#define MPC83xx_TSEC_TX_INT     (0)
#define MPC83xx_TSEC_RX_INT     (1)
#define MPC83xx_TSEC_ERR_INT    (2)
#define MPC83XX_TSEC_NUM_ISRS   (3)

#define etsec_lock()          _int_disable()
#define etsec_unlock()        _int_enable()

#define RX_INC(index)   if (++index == BSPCFG_RX_RING_LEN) index = 0
#define TX_INC(index)   if (++index == BSPCFG_TX_RING_LEN) index = 0
                         
#define ENET_FRAMESIZE_ALIGN(n)  ((n) + (-(n) & 63))
#define ENET_BD_ALIGN(n)         ((n) + (-(n) & 8))

#define TSEC_WRITE_WITH_DELAY(r,v) { int i; MPC83xx_etsec_write(&r,v,#r);  for(i = 0; i < 20000; i++) {} }
#define TSEC_WRITE(r,v) MPC83xx_etsec_write(&r,v,#r)

typedef uint_16 bd_index_t;
typedef PCB2 MPC83XX_TSEC_RX_PCB, _PTR_ MPC83XX_TSEC_RX_PCB_PTR;

typedef struct mpc83xx_tsec_context_struct {
   MPC83xx_ETSEC_STRUCT_PTR TSEC_ADDRESS;
   MPC83xx_ETSEC_STRUCT_PTR PHY_PTR;

   uint_16                 AlignedRxBufferSize;
   uint_16                 AlignedTxBufferSize;
   
   /*
   **    The Receive-Side State
   **
   ** RxPCBHead and RxPCBTail are the head and tail of a linked list
   ** of available PCBs for receiving packets.  RxEntries is
   ** the length of this list.
   **
   ** NextRxBD points to the 'first' queued receive descriptor, i.e., usually
   ** the one that RBPTR is pointing to.  When an RXF interrupt occurs,
   ** NextRxBD is pointing to the first descriptor with a received packet.
   ** The packets is forwarded to the upper layers, and NextRxBD is incremented.
   **
   ** LastRxBD points to the 'last' queued receive descriptor, i.e., the last
   ** one with E=1.  The LastRxBD descriptor usually precedes the LastRxBD descriptor.
   ** When the upper layers free a received packet, it gets placed at LastRxBD
   ** (with E=1), and LastRxBD is incremented.
   */

   PCB_PTR                       RxPCBHead;
   PCB_PTR                       RxPCBTail;
   
   uint_32                       CurrentRxFrag;
   ENET_ECB_STRUCT_PTR           CurrentRxECB;
   PCB_FRAGMENT                  FRAGS[MPC83XX_TSEC_MAX_FRAGS];

   bd_index_t                    ActiveRxBDs;
   bd_index_t                    NextRxBD;
   bd_index_t                    LastRxBD;
   bd_index_t                    NumRxBDs;

   /*
   **    The Transmit-Side State
   **
   ** TxPCBS_PTR is an array of pointers to the PCBs queued on the transmit ring.
   ** AvailableTxBDs is the number of free entries on the ring.
   **
   ** NextTxBD points to the first available transmit descriptor (when AvailableTxBDs>0),
   ** or to LastTxBD (when AvailableTxBDs==NumTxBDs).  It is the descriptor that will next
   ** be queued onto the transmit ring, as soon as there's a packet to send
   ** and room on the transmit ring.
   **
   ** LastTxBD points to the 'last' queued transmit descriptor, i.e., the one
   ** that TBPTR is pointing to.  When a TXB interrupt occurs, LastTxBD is
   ** pointing to the transmitted buffer.  The buffer is freed, and LastTxBD is
   ** incremented.
   **
   ** TxErrors keeps track of all the errors that occur during transmission
   ** of a frame comprised of multiple buffers.
   */

   PCB_PTR *                     TxPCBS_PTR;
   bd_index_t                    AvailableTxBDs;
   bd_index_t                    NextTxBD;
   bd_index_t                    LastTxBD;
   bd_index_t                    NumTxBDs;
   uint_32                       TxErrors;

   MPC83XX_TSEC_RX_PCB_PTR       RX_PCB_BASE;
   pointer                       UNALIGNED_RING_PTR;        
   VMPC83xx_TSEC_BD_STRUCT_PTR   TSEC_RX_RING_PTR; 
   VMPC83xx_TSEC_BD_STRUCT_PTR   TSEC_TX_RING_PTR; 
   pointer                       UNALIGNED_BUFFERS;  
   uchar_ptr                     RX_BUFFERS;  
   uchar_ptr                     TX_BUFFERS;  
   uchar_ptr                     SMALL_BUFFERS;  
   uchar_ptr                     LARGE_BUFFERS;  
   uint_32                       FREE_TX;
   uint_32                       FREE_TX_SMALL;
   
   /* These fields are kept only for ENET_shutdown() */
   void _CODE_PTR_               OLDISR_PTR[MPC83XX_TSEC_NUM_ISRS];
   pointer                       OLDISR_DATA[MPC83XX_TSEC_NUM_ISRS];
} MPC83XX_TSEC_CONTEXT_STRUCT, * MPC83XX_TSEC_CONTEXT_STRUCT_PTR;

extern const   ENET_MAC_IF_STRUCT MPC83xx_MAC_IF;
extern const   ENET_PHY_IF_STRUCT MPC83xx_PHY_IF;
extern const uint_32 MPC83xx_etsec_vectors[MPC83xx_ETSEC_DEVICE_COUNT][MPC83xx_ETSEC_NUM_INTS];

extern void MPC83xx_etsec_write(vuint_32_ptr addr, uint_32 val, char * reg);
extern uint_32 MPC83xx_etsec_initialize (ENET_CONTEXT_STRUCT_PTR);
extern uint_32 MPC83xx_etsec_shutdown (ENET_CONTEXT_STRUCT_PTR);
extern uint_32 MPC83xx_etsec_send_MAC (ENET_CONTEXT_STRUCT_PTR,PCB_PTR, uint_32, uint_32, uint_32);
extern uint_32 MPC83xx_etsec_join_MAC (ENET_CONTEXT_STRUCT_PTR, ENET_MCB_STRUCT_PTR);
extern uint_32 MPC83xx_etsec_rejoin_MAC (ENET_CONTEXT_STRUCT_PTR);
extern uint_32 MPC83xx_etsec_get_speed (ENET_CONTEXT_STRUCT_PTR);
extern uint_32 MPC83xx_etsec_write_mdio (ENET_CONTEXT_STRUCT_PTR, uint_32 , uint_32, uint_32);
extern uint_32 MPC83xx_etsec_read_mdio (ENET_CONTEXT_STRUCT_PTR, uint_32, uint_32_ptr, uint_32);
extern void MPC83xx_etsec_rx_add(PCB_PTR  pcb_ptr);
extern void MPC83xx_etsec_RX_ISR ( ENET_CONTEXT_STRUCT_PTR  enet_ptr );
extern void MPC83xx_etsec_TX_ISR ( ENET_CONTEXT_STRUCT_PTR  enet_ptr );
extern void MPC83xx_etsec_ERR_ISR ( ENET_CONTEXT_STRUCT_PTR  enet_ptr );

extern MPC83xx_ETSEC_STRUCT_PTR MPC83xx_etsec_get_base_address( uint_32 device );
extern uint_32 MPC83xx_etsec_get_vector(uint_32 device, uint_32 vector_index);
extern void MPC83xx_etsec_clock_config( uint_32 device );
extern void MPC83xx_etsec_pin_config( uint_32 device );

extern boolean MPC83xx_etsec_install_isrs( ENET_CONTEXT_STRUCT_PTR enet_ptr  ); 
extern boolean MPC83xx_etsec_enable_ints( ENET_CONTEXT_STRUCT_PTR enet_ptr  ); 
extern void MPC83xx_etsec_uninstall_all_isrs( ENET_CONTEXT_STRUCT_PTR enet_ptr); 
extern uint_32 MPC83xx_etsec_get_vector(uint_32 device, uint_32 vector_index);
extern void MPC83xx_etsec_free_context( MPC83XX_TSEC_CONTEXT_STRUCT_PTR tsec_context_ptr );


#endif

/* EOF */
